package com.qiangesoft.blog.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qiangesoft.blog.common.constants.FieldConstants;
import com.qiangesoft.blog.common.mvc.PageQuery;
import com.qiangesoft.blog.common.mvc.PageResultVO;
import com.qiangesoft.blog.common.result.ResponseResult;
import com.qiangesoft.blog.core.entity.BlogArticleTag;
import com.qiangesoft.blog.core.entity.BlogTag;
import com.qiangesoft.blog.core.mapper.BlogTagMapper;
import com.qiangesoft.blog.core.pojo.vo.BlogTagVO;
import com.qiangesoft.blog.core.service.IBlogArticleTagService;
import com.qiangesoft.blog.core.service.IBlogTagService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static com.qiangesoft.blog.common.constants.FieldConstants.LIMIT_ONE;

/**
 * <p>
 * 标签 服务实现类
 * </p>
 *
 * @author qiange
 * @since 2023-06-05
 */
@Service
public class BlogTagServiceImpl extends ServiceImpl<BlogTagMapper, BlogTag> implements IBlogTagService {

    @Autowired
    private IBlogArticleTagService blogArticleTagService;

    @Override
    public PageResultVO<BlogTag> listTags(PageQuery pageQuery, String name) {
        PageResultVO<BlogTag> pageResultVO = new PageResultVO<>();
        Integer pageNum = pageQuery.getPageNum();
        Integer pageSize = pageQuery.getPageSize();
        pageResultVO.setPageNum(pageNum);
        pageResultVO.setPageSize(pageSize);

        LambdaQueryWrapper<BlogTag> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(name), BlogTag::getName, name);
        Page<BlogTag> page = baseMapper.selectPage(new Page<>(pageNum, pageSize), queryWrapper);
        pageResultVO.setTotal(page.getTotal());
        pageResultVO.setPages(page.getPages());

        List<BlogTag> records = page.getRecords();
        for (BlogTag record : records) {
            int count = blogArticleTagService.count(new LambdaQueryWrapper<BlogArticleTag>().eq(BlogArticleTag::getTagId, record.getId()));
            record.setArticleNum(count);
        }
        pageResultVO.setResults(records);
        return pageResultVO;
    }

    /**
     * 标签详情
     *
     * @param id
     * @return
     */
    @Override
    public ResponseResult getTagsById(Long id) {
        BlogTag tags = baseMapper.selectById(id);
        return ResponseResult.success(tags);
    }

    /**
     * 添加标签
     *
     * @param tags
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult insertTag(BlogTag tags) {
        validateName(tags.getName());
        baseMapper.insert(tags);
        return ResponseResult.success();
    }

    /**
     * 修改标签
     *
     * @param tags
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult updateTag(BlogTag tags) {
        BlogTag entity = baseMapper.selectById(tags.getId());
        if (!entity.getName().equals(tags.getName())) validateName(tags.getName());
        baseMapper.updateById(tags);
        return ResponseResult.success();
    }

    /**
     * 删除标签
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult deleteById(Long id) {
        baseMapper.deleteById(id);
        return ResponseResult.success();
    }

    /**
     * 批量删除标签
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult deleteBatch(List<Long> ids) {
        baseMapper.deleteBatchIds(ids);
        return ResponseResult.success();
    }

    /**
     * 置顶标签
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult top(Long id) {
        BlogTag tags = baseMapper.selectOne(new QueryWrapper<BlogTag>()
                .last(LIMIT_ONE).orderByDesc(FieldConstants.SORT));
        Assert.isTrue(!tags.getId().equals(id), "改标签已在最顶端!");
        BlogTag entity = BlogTag.builder().id(id).sort(tags.getSort() + 1).build();
        int rows = baseMapper.updateById(entity);
        return rows > 0 ? ResponseResult.success() : ResponseResult.error();
    }


    //    ----web端方法开始-----

    /**
     * 标签列表
     *
     * @return
     */
    @Override
    public List<BlogTagVO> webList() {
        List<BlogTag> tagList = this.list();

        QueryWrapper<BlogArticleTag> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("tag_id as tagId,count(id) num")
                .groupBy("tag_id");
        List<Map<String, Object>> mapList = blogArticleTagService.listMaps(queryWrapper);

        List<BlogTagVO> voList = new ArrayList<>();
        for (BlogTag blogTag : tagList) {
            BlogTagVO vo = new BlogTagVO();
            vo.setId(blogTag.getId());
            vo.setName(blogTag.getName());

            Optional<Map<String, Object>> first = mapList.stream().filter(item -> blogTag.getId().equals(item.get("tagId"))).findFirst();
            if (first.isPresent()) {
                vo.setArticleNum(Integer.parseInt(first.get().get("num").toString()));
            } else {
                vo.setArticleNum(0);
            }
            voList.add(vo);
        }
        return voList;
    }

    //-----------自定义方法开始------------
    public void validateName(String name) {
        BlogTag entity = baseMapper.selectOne(new QueryWrapper<BlogTag>().eq(FieldConstants.NAME, name));
        Assert.isNull(entity, "标签名已存在!");
    }
}
